﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Platform.Linq
{

	internal sealed class MapReduceKeyComparer<TKey> : IEqualityComparer<TKey>
	{
		private List<Func<TKey, object>> gets = new List<Func<TKey, object>>();

		private MapReduceKeyComparer()
		{ }


		public static MapReduceKeyComparer<TKey> Create<TEmit>( Expression<Func<TEmit, TKey>> keySelector )
		{
			var comparer = new MapReduceKeyComparer<TKey>();

			var keyExtractor = new MapReduceKeyExtractor<TKey>( keySelector );
			comparer.gets = keyExtractor.ExtractGets();

			return comparer;
		}


		internal int KeyCount
		{ get { return this.gets.Count; } }

		#region IEqualityComparer<TKey> Members

		public bool Equals( TKey x, TKey y )
		{
			bool isEquals = true;
			int index = 0;
			int count = this.gets.Count;

			while ( isEquals && index < count )
			{
				Func<TKey, object> getter = this.gets[ index ];

				isEquals = Object.Equals( getter( x ), getter( y ) );
				index++;
			}

			return isEquals;
		}

		public int GetHashCode( TKey obj )
		{
			int code = this.gets[ 0 ]( obj ).GetHashCode();

			int index = 1;
			int count = this.gets.Count;

			while ( index < count )
				code ^= this.gets[ index++ ]( obj ).GetHashCode();

			return code;
		}

		#endregion
	}

}
